/*
 *        (C) COPYRIGHT Ingenic Limited.
 *             ALL RIGHTS RESERVED
 *
 * File       : ingenic_mnni.h
 * Authors    : thu@taurus
 * Create Time: 2023-05-29:16:21:00
 * Description:
 *
 */

#ifndef __INGENIC_MNNI_H__
#define __INGENIC_MNNI_H__

#include <string>
#include <vector>

#include "common_type.h"
#include "core/uranus_api.h"
#include "core/uranus_tensor.h"
using namespace std;

namespace magik {
namespace uranus {

class Network {
public:
  Network() = default;
  virtual ~Network() = default;

  // Delete the copy constructor
  Network(const Network &) = delete;
  // Delete the copy assignment operator
  Network &operator=(const Network &) = delete;

  // Virtual method overridden by subclasses to process the module
  // being operated on.
  /**
   * @brief Perform the forward infernce of the network.
   * @return The venus status code (network executed successfully if 0).
   */
  virtual int run() = 0;

  /**
   * @brief Get a network input tensor.
   * @param index    Input tensor index.
   * @return Network input tensor of the specified index.
   */
  virtual Tensor get_input(int index = 0) const = 0;

  /**
   * @brief Get a network input tensor.
   * @param name    Input tensor name.
   * @return Network input tensor of the specified name.
   */
  virtual Tensor get_input(std::string &name) const = 0;

  /**
   * @brief Get a network output tensor.
   * @param index    Output tensor index.
   * @return Network output tensor of the specified index.
   */
  virtual const Tensor get_output(int index = 0) const = 0;

  /**
   * @brief Get a network output tensor.
   * @param name    Output tensor name.
   * @return Network output tensor of the specified name.
   */
  virtual const Tensor get_output(std::string &name) const = 0;

  /**
   * @brief Get all the input names to the network.
   * @return Network input tensor names.
   */
  virtual std::vector<std::string> get_input_names() const = 0;

  /**
   * @brief Get all the output names to the network.
   * @return Network output tensor names.
   */
  virtual std::vector<std::string> get_output_names() const = 0;

  /**
   * @brief Reshape tensors to the network.
   */
  virtual void reshape() = 0;

  /**
   * @brief Gets the size of the memory space required for the network forward
   * inference phase.
   * @return The size of memory space required for the model forward inference
   * phase.
   */
  virtual int64_t get_forward_memory_size() const = 0;

  /**
   * @brief Free memory allocated for network forward inference.
   * @return The venus status code.
   */
  virtual int free_forward_memory() = 0;

  /**
   * @brief Alloc memory allocated for network forward inference.
   * @return The venus status code.
   */
  virtual int alloc_forward_memory() = 0;

  /**
   * @brief Free memory allocated for all inputs to the network.
   * @return The venus status code.
   */
  virtual int free_inputs_memory() = 0;
};

/**
 * @brief Load a magik model.
 * @param net                magik model that is acquired.
 * @param model_path         model file path.
 * @param config             magik model parse config
 * @return The venus status code.
 */

int magik_load_model(Network *&net, const void *model_path,
                     MagikModelParseConfig config);
int magik_load_model(Network *&net, const void *model_path);
/**
 * @brief Load multiple magik models.
 * @param nets               magik models that is acquired.
 * @param num_net            loaded models number.
 * @param model_path         model file path.
 * @param config             magik model parse config
 * @return The venus status code.
 */

int magik_load_model(Network **&net, int &net_num, const void *model_path,
                     MagikModelParseConfig config);
int magik_load_model(Network **&net, int &net_num, const void *model_path);
/**
 * @brief Destroy magik model.
 * @param net                magik model that needs to be destroyed.
 * @return The venus status code.
 */
int magik_destroy_model(Network *&net);

/**
 * @brief Get magik core version.
 * @return The magik core version.
 */
unsigned char *get_magik_core_version(void);

} // namespace uranus
} // namespace magik

#endif /* __INGENIC_MNNI_H__ */
